﻿using System.Globalization;
using System.Linq;
using Bots.Gatherbuddy;
using Styx;
using Styx.Plugins;
using Styx.WoWInternals;
using Styx.CommonBot;
using Styx.Common;
using System;
using System.Collections.Generic;
using Styx.WoWInternals.WoWObjects;

namespace HBTracker
{
    public class HBTracker : HBPlugin
    {
        public static Boolean On = false;
        public static Boolean IsInit=false;
        public static Dictionary<string, string> Data;

        public CultureInfo MyCulture = CultureInfo.InvariantCulture;

        DateTime _lastUpdate;
        DateTime _startTime;

        private static readonly LocalPlayer Me = StyxWoW.Me;

        public override string Author
        {
            get { return "toNyx"; }
        }

        public override string Name
        {
            get { return "HBTracker"; }
        }

        public override Version Version
        {
            get { return new Version(1, 0, 0); }
        }

        public override void OnButtonPress()
        {
            new FormSettings().ShowDialog();
        }
        public override bool WantButton { get { return true; } }
        public override string ButtonText { get { return "Settings"; } }

        public override void OnEnable()
        {
            //Enable AutoLoot
            Lua.DoString("SetCVar('AutoLootDefault','1')");

            if (!IsInit)
            {
                if (HBTrackerSettings.Instance.Pdebug){ Logging.Write("[HBTracker] Version {0} initalized", Version); }

                On = true;

                TrackerEvents.AttachEvents();

                Data = new Dictionary<string, string>
                           {
                               {"version", Version.ToString()},
                               {"name", ""},
                               {"level", ""},
                               {"xp", ""},
                               {"xp_needed", ""},
                               {"screen", ""},
                               {"nodeh", ""},
                               {"runningtime", ""},
                               {"xph", ""},
                               {"timetolevel", ""},
                               {"kills", ""},
                               {"killsh", ""},
                               {"honor", ""},
                               {"honorh", ""},
                               {"death", ""},
                               {"deathh", ""},
                               {"bgwin", ""},
                               {"bglost", ""},
                               {"server", ""},
                               {"gbankmoney", ""}
                           };

                // init start values

                Data["level"] = Convert.ToInt32(Me.Level).ToString(MyCulture);
                Data["apikey"] = HBTrackerSettings.Instance.ApiKey;
                Data["server"] = Me.RealmName;
                Data["name"] = Me.Name;

                if (Convert.ToInt32(Me.Experience) > 0 && Convert.ToInt32(Me.Experience) <= Int32.MaxValue) Data["xp"] = Convert.ToInt32(Me.Experience).ToString(MyCulture);
                if (Convert.ToInt32(Me.NextLevelExperience) > 0 && Convert.ToInt32(Me.NextLevelExperience) >= Int32.MaxValue) Data["xp_needed"] = Convert.ToInt32(Me.NextLevelExperience).ToString(MyCulture);

                _lastUpdate = DateTime.Now;
                _startTime = DateTime.Now;

                if (HBTrackerSettings.Instance.Pdebug){ Logging.Write("[HBTracker] Initialization done"); }

                IsInit = true;

            }
        }
        public override void OnDisable()
        {
            if (HBTrackerSettings.Instance.Pdebug) Logging.Write("[HBTracker] Dispose method started");

            On = false;

            TrackerEvents.DetachEvents();

            Data.Values.Where(key => key != "gbankmoney").ForEach(delegate(string myKey) { Data[myKey] = ""; });

            IsInit = false;

            if (HBTrackerSettings.Instance.Pdebug) Logging.Write("[HBTracker] Dispose method done");

        }

        public override void Pulse()
        {
            Updater();
        }

        private void Updater()
        {
            if (_lastUpdate.AddSeconds(HBTrackerSettings.Instance.RefreshRate) < DateTime.Now)
            {
                GetData();
                Send(Data);
                _lastUpdate = DateTime.Now;
            }
        }

        private void GetData()
        {
            try
            {
                // fill rest data
                using (StyxWoW.Memory.AcquireFrame()){

                    Data["level"] = Convert.ToInt32(Me.Level).ToString(MyCulture);
                    Data["faction"] = Me.IsAlliance.ToString();

                    Data["apikey"] = HBTrackerSettings.Instance.ApiKey;
                    Data["runningtime"] = (DateTime.Now - _startTime).TotalSeconds.ToString(MyCulture);
                    Data["xp"] = Convert.ToUInt32(Me.Experience).ToString(MyCulture);
                    Data["xp_needed"] = Convert.ToUInt32(Me.NextLevelExperience).ToString(MyCulture);
                    Data["xph"] = Convert.ToUInt32(GameStats.XPPerHour).ToString(MyCulture);
                    Data["timetolevel"] = Convert.ToUInt32(GameStats.TimeToLevel.TotalSeconds).ToString(MyCulture);

                    Data["kills"] = Convert.ToUInt32(GameStats.MobsKilled).ToString(MyCulture);
                    Data["killsh"] = Convert.ToUInt32(GameStats.MobsPerHour).ToString(MyCulture);

                    Data["honor"] = Convert.ToUInt32(GameStats.HonorGained).ToString(MyCulture);
                    Data["honorh"] = Convert.ToUInt32(GameStats.HonorPerHour).ToString(MyCulture);
                    Data["bgwin"] = Convert.ToUInt32(GameStats.BGsWon).ToString(MyCulture);
                    Data["bglost"] = Convert.ToUInt32(GameStats.BGsLost).ToString(MyCulture);

                    Data["gold"] = Convert.ToUInt32(Me.Copper).ToString(MyCulture);
                    Data["nodeh"] = JSON.JsonEncode(GatherbuddyBot.NodeCollectionCount);

                    Data["nodeh"] = GatherbuddyBot.NodeCollectionCount.Values.Sum().ToString(MyCulture);

                }
            }
            catch (Exception e)
            {
                if (HBTrackerSettings.Instance.Debug) Logging.Write("[HBTracker] Error -> {0} | stack: {1} | IException : {2}", e.Message, e.StackTrace, e.InnerException);
            }
        }

        public static void Send(Dictionary<string, string> datax)
        {	
            if (On && datax["server"] != "" && datax["apikey"] != "")
            { 
                try
                {
                    if (HBTrackerSettings.Instance.Pdebug) Logging.Write("[HBTracker] Sending data for {0} - {1}", datax["server"], datax["name"]);
					
                    var sendParam = new string[datax.Count + 1];
                    var sendVal = new string[datax.Count + 1];
                    int i = 0;
                    foreach (var pair in datax)
                    {
						if (pair.Value != "" && pair.Value != "0" && HBTrackerSettings.Instance.Pdebug)
                            Logging.Write("[HBTracker] {0} = {1}", pair.Key, pair.Value);
                        sendParam[i] = pair.Key;
                        sendVal[i] = pair.Value;
                        i++;
                    }

                    Data["screen"] = "";

					string response = "";
			
                    if (HBTrackerSettings.Instance.OwnUrl.Length > 7) { response = Util.HttpPost(HBTrackerSettings.Instance.OwnUrl, sendParam, sendVal); }

                    if (response != "")
                    {
                        if (HBTrackerSettings.Instance.Pdebug) Logging.Write("[HBTracker]  We got Response! ( {0} )", response);

                        switch (response)
                        {
                            case "":
                                break;
                            case "success":
                                break;
                            case "killwow":
                                Logging.Write("[HBTracker] {0}", "Kill Wow requested!");
                                StyxWoW.Memory.Process.Kill();
                                break;
                            case "screen":
                                TrackerEvents.TakeScreen();
                                break;
                            case "stophb":
                                Logging.Write("[HBTracker] {0}", "Stop HB requested!");
                                TreeRoot.Stop();
                                break;
                            case "starthb":
                                Logging.Write("[HBTracker] {0}", "Start HB requested!");
                                TreeRoot.Start();
                                break;
                            default:
                                Logging.Write("[HBTracker] {0}", response);
                                break;

                        }
                    }

                    if (HBTrackerSettings.Instance.Pdebug) Logging.Write("[HBTracker] Data sent !");
					
                }
                catch (InvalidCastException e)
                {
                    if (HBTrackerSettings.Instance.Debug) Logging.Write("[HBTracker] Error (Cast) -> {0}", e.Message);
                }
                catch (Exception e)
                {
                    if (HBTrackerSettings.Instance.Debug) Logging.Write("[HBTracker] Error (Send) -> {0}", e.Message);
                }   
            }
            else
            {
                if(Data["apikey"] == "")
                    Logging.Write("[HBTracker] Error -> API Key not set.");
            }
            
        }
    }
}
